{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Debugging Faster R-CNN Networks"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import sys\n",
    "sys.path.append('../')\n",
    "\n",
    "import numpy as np\n",
    "np.set_printoptions(precision=3)\n",
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Check Cythonized modules working"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### bbox_overlaps"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from Lib.bbox_overlaps import bbox_overlaps"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "boxes = np.array([[1,3,2,4],\n",
    "                  [2,5,1,8],\n",
    "                  [3,4,9,9],\n",
    "                  [1,9,7,11]],dtype=np.float)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "query_boxes = np.array([[1,3,2,4],\n",
    "                  [5,3,7,4],\n",
    "                  [1,8,10,12],\n",
    "                  [0,2,3,5],\n",
    "                  [0,3,2,9],\n",
    "                  [2,1,3,4]],dtype=np.float)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.   ,  0.   ,  0.   ,  0.25 ,  0.19 ,  0.2  ],\n",
       "       [ 0.   ,  0.   ,  0.   ,  0.   ,  0.   ,  0.   ],\n",
       "       [ 0.   ,  0.067,  0.179,  0.036,  0.   ,  0.02 ],\n",
       "       [ 0.   ,  0.   ,  0.42 ,  0.   ,  0.05 ,  0.   ]])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bbox_overlaps(boxes,query_boxes)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### nms"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from Lib.nms_wrapper import nms"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "proposals = 10*np.array([[2,1,12,21,0],\n",
    "                     [10,5,14,18,.1],\n",
    "                     [5,3,11,14,.2],\n",
    "                     [1,4,20,20,.3]],dtype=np.float32)\n",
    "copies = np.random.choice(4,256,p=[0.1,0.2,0.3,0.4])\n",
    "proposals = proposals[copies,:]\n",
    "perturbations = np.random.randint(8,size=(256,4))\n",
    "perturbations = np.concatenate((perturbations,np.zeros([256,1])),1)\n",
    "proposals = np.array(proposals + perturbations,dtype=np.float32)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[  11.,   42.,  207.,  206.,    3.],\n",
       "       [  56.,   30.,  113.,  147.,    2.],\n",
       "       [ 106.,   51.,  146.,  181.,    1.],\n",
       "       [  25.,   15.,  121.,  213.,    0.]], dtype=float32)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "keep = nms(proposals,0.7)\n",
    "proposals[keep,:]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Test fast_rcnn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from Networks.convnet import convnet\n",
    "from Networks.faster_rcnn_networks import rpn, roi_proposal, fast_rcnn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Global Dictionary of Flags\n",
    "flags = {\n",
    "    'data_directory': '../Data/MNIST/',\n",
    "    'save_directory': '../Logs/summaries/',\n",
    "    'model_directory': 'resnet101/',\n",
    "    'restore': False,\n",
    "    'restore_file': 'start.ckpt',\n",
    "    'datasets': 'MNIST',\n",
    "    'image_dim': 28,\n",
    "    'hidden_size': 10,\n",
    "    'num_classes': 10,\n",
    "    'batch_size': 1,\n",
    "    'display_step': 200,\n",
    "    'weight_decay': 1e-7,\n",
    "    'lr_decay': 0.999,\n",
    "    'num_epochs': 10,\n",
    "    'lr_iters': [(5e-3, 5000), (5e-3, 7500), (5e-4, 10000), (5e-5, 10000)],\n",
    "    'anchor_scales': [1,2,4]\n",
    "}\n",
    "eval_mode = False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Set up inputs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "x = tf.placeholder(tf.float32, [1, 128, 128, 3], name='x')\n",
    "gt_boxes = tf.placeholder(tf.int64, [1, 5], name='gt')\n",
    "im_dims = tf.placeholder(tf.int64, [1, 2], name='im_dims')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Convolutional Feature Extractor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "conv_1 output: (1, 64, 64, 64)\n",
      "conv_2 output: (1, 32, 32, 96)\n",
      "conv_3 output: (1, 16, 16, 128)\n",
      "conv_4 output: (1, 8, 8, 172)\n",
      "conv_5 output: (1, 4, 4, 256)\n"
     ]
    }
   ],
   "source": [
    "cnn = convnet(x, [5, 3, 3, 3, 3], [64, 96, 128, 172, 256], strides=[2, 2, 2, 2, 2])\n",
    "featureMaps = cnn.get_output()\n",
    "_feat_stride = cnn.get_feat_stride()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### RPN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "conv_1 output: (1, 4, 4, 512)\n",
      "conv_1 output: (1, 4, 4, 18)\n",
      "conv_1 output: (1, 4, 4, 36)\n"
     ]
    }
   ],
   "source": [
    "rpn_net = rpn(featureMaps,gt_boxes,im_dims,_feat_stride,eval_mode)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "TensorShape([Dimension(1), Dimension(4), Dimension(4), Dimension(18)])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rpn_cls_score = rpn_net.get_rpn_cls_score()\n",
    "rpn_cls_score.get_shape()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "TensorShape(None)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rpn_labels = rpn_net.get_rpn_labels()\n",
    "rpn_labels.get_shape()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "TensorShape([Dimension(1), Dimension(4), Dimension(4), Dimension(36)])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rpn_bbox_pred = rpn_net.get_rpn_bbox_pred()\n",
    "rpn_bbox_pred.get_shape()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "TensorShape(None)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rpn_bbox_targets = rpn_net.get_rpn_bbox_targets()\n",
    "rpn_bbox_targets.get_shape()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "TensorShape(None)"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rpn_bbox_outside_weights = rpn_net.get_rpn_bbox_outside_weights()\n",
    "rpn_bbox_outside_weights.get_shape()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### ROI Proposal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "rpn_cls_score = rpn_net.get_rpn_cls_score()\n",
    "rpn_bbox_pred = rpn_net.get_rpn_bbox_pred()\n",
    "roi_proposal_net = roi_proposal(rpn_net, gt_boxes, im_dims, eval_mode)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "TensorShape([Dimension(None), Dimension(5)])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "roi_proposal_net.get_rois().get_shape()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "TensorShape(None)"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "roi_proposal_net.get_labels().get_shape()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "TensorShape(None)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "roi_proposal_net.get_bbox_targets().get_shape()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Fast RCNN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "flat_1 output: (?, 12544)\n",
      "fc_1 output: (?, 1024)\n",
      "fc_2 output: (?, 1024)\n",
      "fc_1 output: (?, 1)\n",
      "fc_1 output: (?, 4)\n"
     ]
    }
   ],
   "source": [
    "fast_rcnn_net = fast_rcnn(featureMaps, roi_proposal_net, eval_mode)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "TensorShape([Dimension(None), Dimension(1)])"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fast_rcnn_net.get_cls_score().get_shape()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "TensorShape([Dimension(None), Dimension(4)])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fast_rcnn_net.get_bbox_refinement().get_shape()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Feed dummy values through net"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Prevent TensorFlow from completely hogging up all GPUs\n",
    "config = tf.ConfigProto(log_device_placement=False)\n",
    "config.gpu_options.per_process_gpu_memory_fraction=0.2\n",
    "sess = tf.InteractiveSession(config=config)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "x_in = np.random.randint(256,size=[1, 128, 128, 3])\n",
    "gt_in = np.array([1,4,16,20,3]).reshape([1,5])\n",
    "im_dims_in = np.array([128]*1*2).reshape([1,2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "sess.run(tf.global_variables_initializer())\n",
    "#sess.run(rpn_bbox_targets,feed_dict={x: x_in, gt: gt_in, im_dims: im_dims_in})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Test ROI pooling layer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "from scipy.misc import imread\n",
    "import matplotlib.pyplot as plt\n",
    "from Lib.roi_pool import roi_pool"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Set up tensorflow graph\n",
    "featMap_tf = tf.placeholder(tf.float32, [None, 128, 128, 1])\n",
    "roi_tf = tf.placeholder(tf.float32, [None, 5])\n",
    "im_dims_tf = tf.placeholder(tf.int32, [None, 2])      \n",
    "\n",
    "pooledFeatures = roi_pool(featMap_tf,roi_tf,im_dims_tf)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nUij4+wAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f47d005dda0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[128 128]]\n"
     ]
    }
   ],
   "source": [
    "imfile = '../Data/clutteredMNIST/Images/test_img85.png'\n",
    "img = imread(imfile)\n",
    "im_dims = np.array(img.shape)\n",
    "im_dims = im_dims.reshape((-1,2))\n",
    "plt.imshow(img)\n",
    "plt.show()\n",
    "print(im_dims)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[  0.,  76.,  26.,  93.,  59.]])"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gt = np.loadtxt('../Data/clutteredMNIST/Annotations/test_img85.txt', ndmin=2)\n",
    "gt_box = gt[:,:4]\n",
    "\n",
    "roi = np.concatenate(([[0]],gt_box),axis=1)\n",
    "roi"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nUij4+wAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f47a809f240>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1, 128, 128, 1)\n"
     ]
    }
   ],
   "source": [
    "# This would be a really dumb output for a CNN, \n",
    "# but for testing purposes, it'll do\n",
    "featureMaps = img[::1,::1]\n",
    "plt.imshow(featureMaps)\n",
    "plt.show()\n",
    "featureMaps = featureMaps.reshape((1,featureMaps.shape[0],featureMaps.shape[1],1))\n",
    "print(featureMaps.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f47a8052dd8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(7, 7)\n",
      "[[  7.11e+01   9.12e+01   3.59e+00   2.12e+01   1.27e+02   8.25e+01\n",
      "    1.16e+01]\n",
      " [  1.60e+02   2.42e+02   2.32e+02   1.18e+02   2.43e+02   2.41e+02\n",
      "    2.33e+02]\n",
      " [  3.62e-01   2.07e+01   2.31e+02   2.34e+02   1.33e+02   2.34e+02\n",
      "    2.34e+02]\n",
      " [  4.03e-01   1.24e+02   2.33e+02   2.36e+02   2.42e+02   2.19e+02\n",
      "    1.05e+02]\n",
      " [  6.28e+01   2.38e+02   2.38e+02   2.35e+02   2.33e+02   3.67e-02\n",
      "    1.30e-03]\n",
      " [  3.51e+00   2.20e+02   2.26e+02   2.34e+02   1.92e+02   0.00e+00\n",
      "    0.00e+00]\n",
      " [  0.00e+00   2.06e+00   1.37e+02   1.64e+02   1.97e+01   0.00e+00\n",
      "    0.00e+00]]\n"
     ]
    }
   ],
   "source": [
    "# Run the graph and pray\n",
    "out = sess.run(pooledFeatures, feed_dict={featMap_tf: featureMaps, roi_tf: roi, im_dims_tf: im_dims})\n",
    "im_out = np.squeeze(out)\n",
    "plt.imshow(im_out)\n",
    "plt.show()\n",
    "print(im_out.shape)\n",
    "np.set_printoptions(precision=2)\n",
    "print(im_out)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Test losses/reshaping"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "41000\n",
      "41001\n",
      "110311\n",
      "110310\n",
      "10816\n",
      "10817\n"
     ]
    }
   ],
   "source": [
    "# Dummy RPN Classification Scores\n",
    "N = 1   # Minibatch size\n",
    "W = 16  # Width of feature maps\n",
    "H = 16  # Height of feature maps\n",
    "K = 9*2 # Number of scores\n",
    "\n",
    "rpn_cls_score = np.array([[[[k + 100*h + 10000*w + 1000000*n for k in range(K)] for h in range(H)] for w in range(W)] for n in range(N)])\n",
    "print(rpn_cls_score[0,4,10,0])\n",
    "print(rpn_cls_score[0,4,10,1])\n",
    "print(rpn_cls_score[0,11,3,11])\n",
    "print(rpn_cls_score[0,11,3,10])\n",
    "print(rpn_cls_score[0,1,8,16])\n",
    "print(rpn_cls_score[0,1,8,17])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Shape: (1, 16, 16, 18)\n",
      "Reshaped: (1, 144, 16, 2)\n",
      "41006\n",
      "41015\n",
      "90702\n",
      "90711\n",
      "130308\n",
      "130317\n"
     ]
    }
   ],
   "source": [
    "# Reshape for softmax\n",
    "shape = rpn_cls_score.shape\n",
    "print(\"Shape: {0}\".format(shape))\n",
    "\n",
    "rpn_cls_score = np.transpose(rpn_cls_score,[0,3,1,2])\n",
    "rpn_cls_score = np.reshape(rpn_cls_score,[shape[0],2,shape[3]//2*shape[1],shape[2]])\n",
    "rpn_cls_score = np.transpose(rpn_cls_score,[0,2,3,1])\n",
    "\n",
    "print(\"Reshaped: {0}\".format(rpn_cls_score.shape))\n",
    "print(rpn_cls_score[0,100,10,0])\n",
    "print(rpn_cls_score[0,100,10,1])\n",
    "print(rpn_cls_score[0,41,7,0])\n",
    "print(rpn_cls_score[0,41,7,1])\n",
    "print(rpn_cls_score[0,141,3,0])\n",
    "print(rpn_cls_score[0,141,3,1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Shape: (2304, 2)\n",
      "[500 509]\n",
      "[301 310]\n",
      "[111007 111016]\n"
     ]
    }
   ],
   "source": [
    "# Reshape for loss\n",
    "rpn_cls_score = np.reshape(rpn_cls_score,[-1,2])\n",
    "print(\"Shape: {0}\".format(rpn_cls_score.shape))\n",
    "\n",
    "print(rpn_cls_score[5,:])\n",
    "print(rpn_cls_score[259,:])\n",
    "print(rpn_cls_score[1978,:])"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python [conda env:tensorflow]",
   "language": "python",
   "name": "conda-env-tensorflow-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
